package com.feige.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feige.constant.Constants;
import com.feige.dao.UserCourseMapper;
import com.feige.pojo.Course;
import com.feige.pojo.User;
import com.feige.pojo.UserCourse;
import com.feige.pojo.vo.UserVo;
import com.feige.result.AjaxResult;
import com.feige.service.CourseService;
import com.feige.service.UserCourseService;
import com.feige.utils.redis.RedisUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户课程表 服务实现类
 * </p>
 *
 * @author feige
 * @since 2020-11-20
 */
@Service
public class UserCourseServiceImpl extends ServiceImpl<UserCourseMapper, UserCourse> implements UserCourseService {

    @Resource
    private CourseService courseService;

    @Resource
    private UserCourseMapper userCourseMapper;


    @Resource
    private RedisUtils redisUtils;



    @Transactional(rollbackFor = { Exception.class })
    @Override
    public AjaxResult joinCourse(UserCourse userCourse) {
        Course course = courseService.getById(userCourse.getCourseId());
        // 相等则说明该用户是该课程的创建者，不用加入
        if (!course.getUserId().equals(userCourse.getUserId())){
            // 查看该课程是否已满
            if (course.getJoinCount() + 1 < course.getMaxJoinCount() ){
                QueryWrapper<UserCourse> wrapper = new QueryWrapper<>();
                wrapper.eq("user_id",userCourse.getUserId())
                        .eq("course_id",userCourse.getCourseId());
                UserCourse userCourse1 = this.getOne(wrapper);
                // 如果不为空则说明该用户已经加入过该课程
                if (ObjectUtil.isEmpty(userCourse1)){
                    int update = courseService.incrementJoinCount(userCourse.getCourseId());
                    boolean save = this.save(userCourse);
                    if (update > 0 && save) {
                        return AjaxResult.success();
                    }else {
                        return AjaxResult.error();
                    }
                }else {
                    return AjaxResult.error(5000,"你已加入该课程，请不要重复操作！");
                }
            }else {
                return AjaxResult.error(5000,"该课程人数已达上限！");
            }
        }else {
            return AjaxResult.error(5000,"你是该课程的创建者，不用加入！");
        }

    }

    @Override
    public List<User> getCourseUser(String courseId, Integer pageNum) {
        long pageSize = Constants.PAGE_SIZE * 4L;
        Map<String, Object> map = new HashMap<>(8);
        map.put("courseId",courseId);
        map.put("pageNum",(pageNum - 1) * pageSize);
        map.put("pageSize", pageSize);
        return userCourseMapper.getCourseUser(map);
    }

    @Override
    public int getCourseUserCount(String courseId) {
        return userCourseMapper.getCourseUserCount(courseId);
    }

    @Override
    public List<Object> getUserIdsByCourseId(String courseId,String userId) {
        String key = Constants.GROUP_USER_ID_KEY + courseId;
        List<Object> userIds = redisUtils.lGet(key, 0, -1);
        List<Object> list = null;
        // 如果Redis中存在就不查询数据库
        if (userIds != null && !userIds.isEmpty()){
            list = userIds;
        }else {
            QueryWrapper<UserCourse> wrapper = new QueryWrapper<>();
            wrapper
                    .select("user_id")
                    .eq("course_id", courseId);
            list = this.list(wrapper).stream().map(UserCourse::getUserId).collect(Collectors.toList());
            if (list != null && !list.isEmpty()){
                // 把课程创建者也加入到列表
                list.add(userId);
                // 设置随机过期时间
                int randomInt = RandomUtil.randomInt(1,10);
                // 把查询数据库的结果存入Redis，以便于下次获取
                redisUtils.lSet(key,list,randomInt * 10L * 60L * 60L);
            }
        }
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult kickOut(String userId, String courseId) {
        UpdateWrapper<UserCourse> wrapper = new UpdateWrapper<>();
        wrapper.eq("course_id",courseId).eq("user_id",userId);
        boolean b = this.remove(wrapper);
        boolean u = courseService.decrementJoinCount(courseId) > 0;
        if (b && u) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error();
        }
    }

    @Override
    public List<UserVo> getCourseUserVoByCourseId(String courseId) {
        return this.baseMapper.getCourseUserVoByCourseId(courseId);
    }
}
